package com.hssy.wululuaplan.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hssy.wululuaplan.common.ExceptionCodeEnum;
import com.hssy.wululuaplan.entity.KeepAccount;
import com.hssy.wululuaplan.exception.CustomException;
import com.hssy.wululuaplan.form.AccountForm;
import com.hssy.wululuaplan.mapper.KeepAccountMapper;
import com.hssy.wululuaplan.service.KeepAccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hssy.wululuaplan.service.SysUserService;
import com.hssy.wululuaplan.vo.account.ChartVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 收支账本记录 服务实现类
 * </p>
 *
 * @author Mr.Hongtao
 * @since 2025-06-18
 */
@Service
public class KeepAccountServiceImpl extends ServiceImpl<KeepAccountMapper, KeepAccount> implements KeepAccountService {
    @Resource
    private SysUserService sysUserService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAccount(AccountForm form, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Integer userId = sysUserService.getUserId(token);
        KeepAccount one = baseMapper.selectOne(Wrappers.<KeepAccount>lambdaQuery()
                .eq(KeepAccount::getUserId, userId)
                .eq(form.getCategory() != null, KeepAccount::getCategory, form.getCategory())
                .eq(KeepAccount::getEvent, form.getEvent())
                .eq(KeepAccount::getType, form.getType())
                .eq(KeepAccount::getMoney, form.getMoney())
                .eq(KeepAccount::getHappenDate, DateUtil.parseDate(form.getHappenDate() + " 00:00:00")));
        if (one == null) {
            KeepAccount entity = new KeepAccount();
            entity.setUserId(userId);
            entity.setCategory(form.getCategory());
            entity.setEvent(form.getEvent());
            entity.setMoney(form.getMoney());
            entity.setType(form.getType());
            entity.setHappenDate(DateUtil.parseDate(form.getHappenDate() + " 00:00:00"));
            baseMapper.insert(entity);
        }else {
            throw new CustomException(500001, "当前记录已存在，请勿重复添加");
        }

    }

    @Override
    public Map<String, BigDecimal> getStatistic(String date, HttpServletRequest request) {
        String dateSql;
        if (date == null) {
            dateSql = DateUtil.format(new Date(), "yyyy-MM-dd");
        }else {
            dateSql = date + "-01";
        }
        String token = request.getHeader("Authorization");
        Integer userId = sysUserService.getUserId(token);
        BigDecimal dayAccount = baseMapper.selectStatistic("day", dateSql, userId);
        BigDecimal monthAccount = baseMapper.selectStatistic("month", dateSql, userId);
        BigDecimal yearAccount = baseMapper.selectStatistic("year", dateSql, userId);
        Map<String, BigDecimal> map = new HashMap<>();
        map.put("day", dayAccount);
        map.put("month", monthAccount);
        map.put("year", yearAccount);

        return map;
    }

    @Override
    public List<KeepAccount> getRecordList(String dateType, String date, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Integer userId = sysUserService.getUserId(token);
        switch (dateType) {
            case "day":
                break;
            case "month":
                date = date + "-01";
                break;
            case "year":
                date = date + "-01-01";
                break;
            default:
                throw new CustomException(ExceptionCodeEnum.PARAM_ERROR);
        }
        return baseMapper.selectMonthList(dateType, date, userId);
    }

    @Override
    public List<ChartVo> getChartDataList(String dateType, String date, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Integer userId = sysUserService.getUserId(token);
        Date date2 = DateUtil.parse(date + " 00:00:00");
        Date startDate;
        Date endDate;
        String[] dateWeek = new String[]{"周一", "周二", "周三", "周四", "周五", "周六", "周日"};
        String[] dateYear = new String[]{"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};
        int times;
        switch (dateType) {
            case "week":
                startDate = DateUtil.beginOfWeek(date2);
                endDate = DateUtil.endOfWeek(date2);
                times = 7;
                break;
            case "month":
                startDate = DateUtil.beginOfMonth(date2);
                endDate = DateUtil.endOfMonth(date2);
                times = (int) DateUtil.betweenDay(startDate, endDate, true) + 1;
                break;
            case "year":
                startDate = DateUtil.beginOfYear(date2);
                endDate = DateUtil.endOfYear(date2);
                times = 12;
                break;
            default:
                throw new CustomException(ExceptionCodeEnum.PARAM_ERROR);

        }
        List<ChartVo> chartVos = baseMapper.selectChartDataList(dateType, startDate, endDate, userId);
        Map<String, BigDecimal> map = chartVos.stream().collect(Collectors.toMap(ChartVo::getDay, ChartVo::getAmountSum));
        // chartVos中每个对象的date都是日期，现将查询出来的chartVos重新进行封装，如果是dateType是week，则将日期改为周一到周日，
        // 查询出来的数据有可能缺少某些天的，缺少的就显示0
        List<ChartVo> resultList = new ArrayList<>();

        for (int i = 0; i < times; i++) {
            ChartVo chartVo = new ChartVo();
            chartVo.setDay(dateType.equals("week") ? dateWeek[i] : "month".equals(dateType) ? (i + 1) + "" : dateYear[i]);
            chartVo.setAmountSum(map.getOrDefault(DateUtil.format(startDate, "year".equals(dateType) ? "yyyy-MM" : "yyyy-MM-dd"), BigDecimal.ZERO));
            resultList.add(chartVo);
            startDate = "year".equals(dateType) ? DateUtil.offsetMonth(startDate, 1) : DateUtil.offsetDay(startDate, 1);
        }
        return resultList;
    }

    public static void main(String[] args) {
//        DateUtil.betweenDay(DateUtil.parseDate("2022-01-01"), "2022-01-31");
        // 今天开始和明天结束相差多少天
        System.out.println(DateUtil.betweenDay(DateUtil.parseDate("2022-01-01"), DateUtil.parseDate("2022-01-31"), true));
    }
}
